package znet

import (
	"fmt"
	"github.com/ShiYY/zinx/ziface"
	"github.com/ShiYY/zinx/zutils"
	"net"
)

type Connection struct {
	// 当前连接的socket TCP套接字
	Conn *net.TCPConn

	// 链接的ID
	ConnID uint32

	// 链接状态
	isClosed bool

	// 链接所绑定的处理业务方法API
	// handlerAPI ziface.HandleFunc

	// 告知当前链接已经退出/停止的 channel
	ExitChan chan bool

	// 该链接处理的方法Router
	Router ziface.IRouter
}

// 初始化链接模块的方法
//func NewConnection(conn *net.TCPConn, connID uint32, callback_api ziface.HandleFunc) *Connection {
func NewConnection(conn *net.TCPConn, connID uint32, router ziface.IRouter) *Connection {
	c := &Connection{
		Conn: conn,
		ConnID: connID,
		// handlerAPI: callback_api,
		Router: router,
		isClosed: false,
		ExitChan: make(chan bool, 1),
	}

	return c
}

// 链接读业务的方法
func (c *Connection) StartReader() {
	fmt.Println("Reader Goroutine is running...")
	defer fmt.Println("connID = ", c.Conn, "Reader is exit, remote addr is ", c.RemoteAddr().String())
	defer c.Stop()

	for  {
		// 读取客户端的数据到buf中, 最大512字节
		//buf := make([]byte, 512)
		buf := make([]byte, zutils.GlobalObject.MaxPackageSize)
		_, err := c.Conn.Read(buf)
		if err != nil {
			fmt.Println("recv buf err ", err)
			continue
		}

		// 得到当前conn数据的Request请求数据
		req := Request{
			conn:c,
			data:buf,
		}

		// 从路由中 找到注册绑定的Conn对应的router调用
		// c.Router.PreHandler(&req)
		// 执行注册的路由方法
		go func(request ziface.IRequest) {
			c.Router.PreHandler(request)
			c.Router.Handle(request)
			c.Router.PostHandler(request)
		}(&req)

		// 调用当前链接所绑定的HandlerAPI
		//if err := c.handlerAPI(c.Conn, buf, len); err != nil {
		//	fmt.Println("ConnID ", c.ConnID, " handler is error ", err)
		//	break
		//}
	}
}

// 启动连接 让当前的连接准备开始工作
func (c *Connection) Start() {
	fmt.Println("Conn Start() ... ConnID = ", c.ConnID)
	// 启动从当前链接读数据的业务
	go c.StartReader()

	// TODO 启动从当前链接写数据的业务
}

// 停止连接 结束当前连接的工作
func (c *Connection) Stop() {
	fmt.Println("Conn Stop().. ConnID = ", c.ConnID)

	// 如果当前链接已经关闭
	if c.isClosed {
		return
	}

	c.isClosed = true

	// 关闭socket链接
	c.Conn.Close()

	// 回收资源
	close(c.ExitChan)
}

// 获取当前连接的绑定socket conn
func (c *Connection) TCPConnection() *net.TCPConn {
	return c.Conn
}

// 获取当前连接模块的连接ID
func (c *Connection) ConnectionID() uint32 {
	return c.ConnID
}

// 获取远程客户端的 TCP状态 IP Port
func (c *Connection) RemoteAddr() net.Addr {
	return c.Conn.RemoteAddr()
}

// 发送数据, 将数据发送给远程的客户端
func (c *Connection) Send(data []byte) error {
	return nil
}
